package com.sj.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.sj.common.dto.user.AdminUserQueryParam;
import com.sj.common.dto.user.UserDto;
import com.sj.common.lang.Const;
import com.sj.entity.Role;
import com.sj.entity.SysMenu;
import com.sj.entity.User;
import com.sj.mapper.UserMapper;
import com.sj.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sj.utils.JwtUtils;
import com.sj.utils.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author 孙峻
 * @since 2022-03-09
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Value("${know.authKey}")
    private String authKey;

    @Autowired
    private RoleService roleService;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private SysMenuService sysMenuService;

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    private ArticleService articleService;

    @Autowired
    private CollectService collectService;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private JwtUtils jwtUtils;

    @Override
    public String getAuthorities(Integer id, String username) {
        String authRedisKey = authKey + "-" + username;

        // 看缓存中是否有权限信息，有就直接返回
        if (redisUtils.hasKey(authRedisKey)) {
            return redisUtils.get(authRedisKey).toString();
        }

        String authorities = "";

        // 获取角色信息
        List<Role> list = roleService.lambdaQuery().inSql(Role::getId, "select role_id from user_role where del = 0 and user_id = " + id).list();
        if (list.size() > 0) {
            authorities = list.stream().map(r -> "ROLE_" + r.getCode()).collect(Collectors.joining(","));
        }

        // 获取权限信息
        List<SysMenu> menuList = sysMenuService.getMenuListByUserId(id);
        if (menuList.size() > 0) {
            if (authorities.length() > 0) {
                authorities += ",";
            }
            authorities = authorities.concat(menuList.stream().map(m -> m.getPerms()).collect(Collectors.joining(",")));
        }

        // 存到缓存中 一个小时后过期
        redisUtils.set(authRedisKey, authorities, jwtUtils.getExpire());
        log.info("用户权限信息{}", authorities);
        return authorities;
    }

    @Override
    public Boolean register() {
        User build = User.builder().id(2)
                .avatarUrl("1.jpg")
                .sex("男")
                .username("root")
                .password(bCryptPasswordEncoder.encode("123123"))
                .nickname("你好").build();
        return this.save(build);
    }

    @Override
    public UserDto getUserDetailInfo(Integer userId) {
        User user = this.getById(userId);
        UserDto userDto = new UserDto();
        BeanUtil.copyProperties(user, userDto, "password");
        // 用户提出问题数量
        userDto.setQuestionNum(articleService.getUserArticleNum(userDto.getId(), Const.ARTICLE_QUESTION));
        // 用户发布博客数量
        userDto.setBlogNum(articleService.getUserArticleNum(userDto.getId(), Const.ARTICLE_BLOG));
        // 用户提出想法数量
        userDto.setIdeaNum(articleService.getUserArticleNum(userDto.getId(), Const.ARTICLE_IDEA));
        // 用户被关注数量
        userDto.setBeFocused(collectService.getCollectNum(userDto.getId(), Const.AUTHOR));
        return userDto;
    }

    @Override
    public IPage<User> getAdminUserList(IPage<User> page, AdminUserQueryParam adminUserQueryParam) {
        return userMapper.getAdminUserList(page, adminUserQueryParam);
    }
}
